<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>大屏渲染</title>
    <link rel="stylesheet" href="../static/layui/css/layui.css">
    <link rel="stylesheet" href="./index.css">

    <script type="importmap">
    {
        "imports": {
        "three": "../three/v170/three.module.min.js",
        "three/addons/": "../three/v170/"
        }
    }
    </script>
</head>

<body>
    <div class="screen-wrapper">
        <!-- 中间threejs的渲染区域 -->
        <div class="three-box" id="three-box"></div>

        <!-- 顶部标题区域 -->
        <div class="screen-top-area">
            <div class="top-title">蓝色可视化大屏大标题</div>
        </div>

        <!-- 左侧图表容器 -->
        <div class="chart-left-wrapper">
            <div class="chart-block">
                <div class="chart-title">左侧第一个图形</div>
                <div class="chart-content">
                    <!-- <img src="./images/side_01.png" /> -->
                    <div id="chart_left_01" class="chart-box"></div>
                </div>
            </div>

            <div class="chart-block">
                <div class="chart-title">左侧第二个图形</div>
                <div class="chart-content">
                    <!-- <img src="./images/side_03.png" /> -->
                    <div id="chart_left_02" class="chart-box"></div>
                </div>
            </div>

            <div class="chart-block">
                <div class="chart-title">左侧第三个图形</div>
                <div class="chart-content">
                    <!-- <img src="./images/side_05.png" /> -->
                    <div id="chart_left_03" class="chart-box"></div>
                </div>
            </div>
        </div>

        <!-- 右侧图表容器 -->
        <div class="chart-right-wrapper">
            <div class="chart-block">
                <div class="chart-title">右侧第一个图形</div>
                <div class="chart-content">
                    <!-- <img src="./images/side_02.png" /> -->
                    <div id="chart_right_01" class="chart-box"></div>
                </div>
            </div>

            <div class="chart-block">
                <div class="chart-title">右侧第二个图形</div>
                <div class="chart-content">
                    <!-- <img src="./images/side_03.png" /> -->
                    <div id="chart_right_02" class="chart-box"></div>
                </div>
            </div>

            <div class="chart-block">
                <div class="chart-title">右侧第三个图形</div>
                <div class="chart-content">
                    <!-- <img src="./images/side_04.png" /> -->
                    <div id="chart_right_03" class="chart-box"></div>
                </div>
            </div>
        </div>
    </div>

    <!-- 标签信息 -->
    <div id="scene-container"></div>
    <div id="labels"></div>

    <div style="position: fixed;left: 0;top: 0;z-index: 9999;display: none;">
        <button id="x_increase">x_增加</button>
        <button id="x_decrease">x_减少</button>
        <button id="y_increase">y_增加</button>
        <button id="y_decrease">y_减少</button>
    </div>

    <div style="position: fixed;left: 0;top: 0;z-index: 9999;">
        <div id="reset_btn">还原</div>
        <div id="add_advice_btn">添加设备</div>
    </div>

    <script src="../static/js/echarts.min-5.5.1.js"></script>
    <script src="../static/layui/layui.js"></script>
    <script type="module">
        import * as THREE from 'three';
        import { CSS2DRenderer, CSS2DObject } from "three/addons/renderers/CSS2DRenderer.js";
        import { CSS3DRenderer, CSS3DObject, CSS3DSprite } from "three/addons/renderers/CSS3DRenderer.js";
        import { TrackballControls } from 'three/addons/controls/TrackballControls.js';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
        import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
        import { DragControls } from 'three/addons/controls/DragControls.js';
        import { GUI } from 'three/addons/libs/lil-gui.module.min.js';

        layui.use(function () {
            var layer = layui.layer;
            var util = layui.util;
            console.log(`bigScreen.html 118 [layer]`, layer);

            let scene, camera, renderer, controls, isPaused;
            let labelRenderer = null;
            let middle_shebei = {};// 设备--用于位置
            let middle_dengguang = null;// 灯光--射光灯
            const cur_ratio = 0.02;// 缩小的系数
            const raycaster = new THREE.Raycaster();
            const mouse = new THREE.Vector2();
            const texturedPlanes = [];
            let labelsArr = [];// 标签数组
            let renderOrder = 1;// 渲染顺序
            const planeCache = {};// 设备平面缓存
            // 背景数组
            let bgcArr = [
                {
                    devicesID: 'bgc_1',// 设备1
                    imgURL: './images/souce_05.png',
                    width: 1393,
                    height: 972,
                    label_offset: [0, 0, 0],// 机台偏移量
                },
                {
                    devicesID: 'bgc_2',// 设备2
                    imgURL: './images/souce_02.png',
                    width: 715,
                    height: 644,
                    label_offset: [0, 0, 0],// 机台偏移量
                }
            ];
            // 设备数组
            let devicesArr = [
                {
                    devicesID: 'machine_1',// 设备1
                    imgURL: './images/souce_01.png',
                    width: 107,
                    height: 96,
                    label_offset: [0.0666999899999869, 0.7156000099999965, 0],// 机台偏移量
                },
                {
                    devicesID: 'machine_2',// 设备2
                    imgURL: './images/souce_03.png',
                    width: 111,
                    height: 102,
                    label_offset: [-0.3499999999999993, 0.2499999999999988, 0],// 机台偏移量
                }
            ];

            // 生成平面
            function createPlane(obj) {
                let imgURL = '';
                let cur_width = 0;
                let cur_height = 0;
                if (obj.devicesID.startsWith('bgc')) {
                    const findIndex = bgcArr.findIndex(item => item.devicesID === obj.devicesID);
                    imgURL = bgcArr[findIndex].imgURL;
                    cur_width = bgcArr[findIndex].width;
                    cur_height = bgcArr[findIndex].height;
                } else if (obj.devicesID.startsWith('machine')) {
                    const findIndex = devicesArr.findIndex(item => item.devicesID === obj.devicesID);
                    imgURL = devicesArr[findIndex].imgURL;
                    cur_width = devicesArr[findIndex].width;
                    cur_height = devicesArr[findIndex].height;
                }
                const textureLoader = new THREE.TextureLoader();
                const texture = textureLoader.load(imgURL);
                texture.anisotropy = renderer.capabilities.getMaxAnisotropy();
                texture.minFilter = THREE.LinearMipmapLinearFilter;// LinearFilter
                texture.magFilter = THREE.LinearFilter;
                texture.generateMipmaps = true;
                texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;

                const geometry = new THREE.PlaneGeometry(cur_width * cur_ratio, cur_height * cur_ratio); // 根据图片比例设置平面尺寸

                const material = new THREE.MeshBasicMaterial({
                    map: texture,
                    transparent: true, // 允许透明
                    opacity: 1, // 设置不透明度（0.0为完全透明，1.0为完全不透明）
                    side: THREE.DoubleSide, // 设置材质为双面
                    blending: THREE.NormalBlending, // 使用正常混合模式
                    // depthTest: false, // 禁用深度测试
                    // depthWrite: false // 禁止写入深度缓冲
                    // metalness: 0, // 设置金属度为 0.5
                    // alphaTest: 0.1,// 透明度阈值
                    // color: 0xffffff, // 设置材质颜色
                });
                material.map.colorSpace = THREE.SRGBColorSpace;

                const plane = new THREE.Mesh(geometry, material);
                plane.material.depthWrite = false;// 该平面在渲染时会写入深度缓冲区
                const p_x = (obj.position || [])[0] || 0;
                const p_y = (obj.position || [])[1] || 0;
                const p_z = (obj.position || [])[2] || 0;
                plane.position.set(p_x, p_y, p_z);
                // plane.renderOrder = obj.renderOrder || 0; // 设置渲染顺序
                plane.renderOrder = renderOrder; // 设置渲染顺序
                renderOrder++;
                scene.add(plane);
                return plane;
            }

            // 添加纹理的函数
            function addTexturedPlane(obj) {
                const plane = createPlane(obj);
                if (obj.labelObj) {
                    createLabel({ plane: plane, ...obj });
                }
            }

            function createLabel(obj) {
                // object.geometry.computeBoundingBox(); // 计算包围盒
                const labelObj = obj.labelObj;
                const findIndex = devicesArr.findIndex(item => item.devicesID === obj.devicesID);
                const label_offset = devicesArr[findIndex].label_offset;// 获取偏移量

                const labelDiv = document.createElement('div');
                labelDiv.className = 'label-wrapper';
                labelDiv.innerHTML = `
                <div class="label-bottom"></div>
                <div class="label-line-1"></div>
                <div class="label-line-2"></div>
                <div class="label-content">
                    <h3 class="label-name">${labelObj.name}</h3>
                    <div class="label-item">进程1:xxxx</div>
                    <div class="label-item">进程2:xxxx</div>
                    <div class="label-item">进程3:xxxx</div>
                    <div class="label-item">进程4:xxxx</div>
                </div>
            `;
                document.getElementById('scene-container').appendChild(labelDiv);
                const labelObject = new CSS3DObject(labelDiv);

                const p_x = (obj.position || [])[0] + label_offset[0];
                const p_y = (obj.position || [])[1] + label_offset[1];
                const p_z = (obj.position || [])[2] + label_offset[2];
                labelObject.position.set(p_x, p_y, p_z);
                labelObject.scale.set(cur_ratio, cur_ratio, cur_ratio);
                middle_shebei['label_' + labelObj.name] = labelObject;
                scene.add(labelObject);

                // 检查labelsArr是否存
                // const find_index = labelsArr.findIndex(item => item.obj.labelObj.uuid === labelObj.uuid);
                // if (find_index === -1) {
                //     labelsArr.push({
                //         labelObject: labelObject,
                //         plane: obj.plane,
                //         obj: obj,
                //     })
                // } else {
                //     labelsArr[find_index] = {
                //         labelObject: labelObject,
                //         plane: obj.plane,
                //         obj: obj,
                //     }
                // }
            }

            function init() {
                scene = new THREE.Scene();
                camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
                camera.rotation.set(0, 0, 0);
                // camera.position.set(10, 10, 10);
                camera.position.set(0, 0, 15);// 正视图
                // camera.lookAt(new THREE.Vector3(0, 0, 0));

                // 创建渲染器
                renderer = new THREE.WebGLRenderer({
                    antialias: true,//
                    alpha: true,// 设置背景透明
                    physicallyCorrectLights: true,// 开启物理光照
                    logarithmicDepthBuffer: true,// 开启深度缓存
                    powerPreference: "high-performance",// 
                });
                renderer.setSize(window.innerWidth, window.innerHeight);
                renderer.setPixelRatio(window.devicePixelRatio);
                document.getElementById('three-box').appendChild(renderer.domElement);

                // var axesHelper = new THREE.AxesHelper(1000);
                // scene.add(axesHelper);// 创建坐标轴辅助对象

                controls = new OrbitControls(camera, renderer.domElement);// 添加控制器
                controls.enablePan = true;// 添加平移功能

                const ambientLight = new THREE.AmbientLight(0xffffff, 1);
                scene.add(ambientLight);// 添加环境光

                const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
                directionalLight.position.set(15, 15, 0);// 设置光源位置
                scene.add(directionalLight);// 添加平行光

                labelRenderer = new CSS3DRenderer();
                labelRenderer.setSize(window.innerWidth, window.innerHeight);
                labelRenderer.domElement.style.position = 'absolute';
                labelRenderer.domElement.style.top = 0;
                labelRenderer.domElement.style.left = 0;
                labelRenderer.domElement.style.zIndex = 3;
                // 不遮挡canvas和threejs的点击事件;导致使用CSS2DObject添加的HTML标签点击事件无效;
                labelRenderer.domElement.style.pointerEvents = 'none';
                document.body.appendChild(labelRenderer.domElement);

                // 添加场景背景图
                addTexturedPlane({
                    devicesID: 'bgc_1',
                    position: [0, 0, 0],
                })
                // 添加流水线
                addTexturedPlane({
                    devicesID: 'bgc_2',
                    position: [-0.799999, -1.3, 0],
                })
                addTexturedPlane({
                    devicesID: 'machine_1',
                    position: [-10.7, -2.4, 0],
                    labelObj: {
                        uuid: '1',
                        name: '1号机台',
                    },
                })
                addTexturedPlane({
                    devicesID: 'machine_1',
                    position: [-8.8, -3.4, 0],
                    labelObj: {
                        uuid: '2',
                        name: '2号机台',
                    },
                })
                addTexturedPlane({
                    devicesID: 'machine_2',
                    position: [-3.6, -6.49, 0],
                    labelObj: {
                        uuid: '3',
                        name: '3号机台',
                    },
                })
                addTexturedPlane({
                    devicesID: 'machine_2',
                    position: [0.908999, -2.3, 0],
                    labelObj: {
                        uuid: '4',
                        name: '4号机台',
                    },
                })
                addTexturedPlane({
                    devicesID: 'machine_2',
                    position: [-1.199999, -0.01222, 0],
                    labelObj: {
                        uuid: '5',
                        name: '5号机台',
                    },
                })
                addTexturedPlane({
                    devicesID: 'machine_2',
                    position: [1.95999, 1.59999, 0],
                    labelObj: {
                        uuid: '6',
                        name: '6号机台',
                    },
                })
                addTexturedPlane({
                    devicesID: 'machine_2',
                    position: [6.2999, -0.2000999, 0],
                    labelObj: {
                        uuid: '7',
                        name: '7号机台',
                    },
                })

                addTexturedPlane({
                    devicesID: 'machine_2',
                    position: [8.4998, -1.400099, 0],
                    labelObj: {
                        uuid: '8',
                        name: '8号机台',
                    },
                })

                // 窗口调整
                window.addEventListener('resize', () => {
                    camera.aspect = window.innerWidth / window.innerHeight;
                    camera.updateProjectionMatrix();
                    renderer.setSize(window.innerWidth, window.innerHeight);
                    labelRenderer.setSize(window.innerWidth, window.innerHeight);
                });

                window.addEventListener('click', onMouseClick, false);

                // 添加键盘事件监听器
                document.addEventListener('keydown', function (event) {
                    // 向上平移
                    if (event.keyCode === 38) {
                        controls.pan(new THREE.Vector3(0, 1, 0));
                    }
                    // 向下平移
                    else if (event.keyCode === 40) {
                        controls.pan(new THREE.Vector3(0, -1, 0));
                    }
                });

                loop();

                setTimeout(() => {
                    addGUI();// 添加GUI
                }, 1000)
            }

            function addGUI() {
                // 创建 GUI，设置gui面板的标题
                // const gui = new GUI({ 'title': "操作区" });
                // const obj = {
                //     color: '#ff0000',
                //     speed: 2.5,
                //     isVisible: true,
                //     selectedOptions: ['苹果🍎']
                // };

                // gui.addColor(obj, 'color').onChange((value) => {
                //     sphereMa.color.set(value);
                // });

                // const sphereFol = gui.addFolder('机台位置');
                // console.log(`bigScreen.html 410 [middle_shebei['1号机台']]`, middle_shebei['1号机台']);
                // sphereFol.add(middle_shebei['2号机台'].position, 'x', -20, 20, 0.1)
                // sphereFol.add(middle_shebei['2号机台'].position, 'y', -20, 20, 0.1)

                // const sphereFol_2 = gui.addFolder('悬浮窗');
                // sphereFol_2.add(middle_shebei['2号机台'].position, 'x', -20, 20, 0.1).onChange(function (value) {
                //     updateLabelPosition(middle_shebei['2号机台'], [value, middle_shebei['2号机台'].position.y, middle_shebei['2号机台'].position.z]);
                // });
                // sphereFol_2.add(middle_shebei['2号机台'].position, 'y', -20, 20, 0.1).onChange(function (value) {
                //     updateLabelPosition(middle_shebei['2号机台'], [middle_shebei['2号机台'].position.x, value, middle_shebei['2号机台'].position.z]);
                // });


                // const cameraFol = gui.addFolder('相机')
                // cameraFol.add(camera.position, 'x', -5, 8, 0.1)
                // cameraFol.add(camera.position, 'y', -5, 8, 0.1)
                // cameraFol.add(camera.position, 'z', -5, 8, 0.1)

                // const lightFol = gui.addFolder('灯光')
                // lightFol.add(light.position, 'x', -5, 5, 0.1)
                // lightFol.add(light.position, 'y', -5, 5, 0.1)
                // lightFol.add(light.position, 'z', -5, 5, 0.1)
            }

            function onMouseClick(event) {
                // 将鼠标位置转换为归一化设备坐标 (-1 到 +1)
                mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
                mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

                // 更新射线
                raycaster.setFromCamera(mouse, camera);

                // 检测射线与场景中的对象相交
                const intersects = raycaster.intersectObjects(scene.children);

                // 如果有相交的对象
                if (intersects.length > 0) {
                    const intersectedPoint = intersects[0].point; // 获取交点
                    const x = Number(intersectedPoint.x.toFixed(6));
                    const y = Number(intersectedPoint.y.toFixed(6));
                    console.log('鼠标x:y', [x, y]); // 输出相对坐标
                }
            }

            // 更新标签位置函数
            function updateLabelPositions() {
                labelsArr.forEach(obj => {
                    const vector = new THREE.Vector3();
                    obj.plane.getWorldPosition(vector);
                    if (obj.labelObject) {
                        obj.labelObject.position.copy(vector);
                        obj.labelObject.lookAt(camera.position);
                    }
                });
            }

            var skip;
            function loop() {
                skip++;
                requestAnimationFrame(loop);
                if (skip < 4) {
                    return;
                } else {
                    skip = 0;
                }

                // updateLabelPositions();// 更新标签位置
                controls.update(); // 更新控制器
                renderer.render(scene, camera); // 渲染场景
                labelRenderer.render(scene, camera); // 渲染标签
            }

            init();

            // 获取按钮元素
            const x_increase = document.getElementById('x_increase');
            const x_decrease = document.getElementById('x_decrease');
            const y_increase = document.getElementById('y_increase');
            const y_decrease = document.getElementById('y_decrease');

            const cur_jitai = '3号机台';
            const selectdevice = 'label_' + cur_jitai;
            function con_position() {
                console.log(`bigScreen.html 543 [middle_shebei]`, middle_shebei);
                console.log(selectdevice, [middle_shebei[selectdevice].position.x, middle_shebei[selectdevice].position.y])
            }
            x_increase.addEventListener('click', (e) => {
                e.preventDefault(); // 防止默认行为
                e.stopPropagation(); // 阻止事件冒泡到全局监听器
                // middle_shebei[selectdevice].position.x = middle_shebei[selectdevice].position.x + 0.8;
                // middle_shebei[selectdevice].updateMatrixWorld(true);
                middle_shebei[selectdevice].position.x += 0.05;
                // if (middle_shebei[selectdevice] instanceof THREE.Object3D) {
                //     console.log('更新前:', middle_shebei[selectdevice].position.x);
                //     middle_shebei[selectdevice].position.x += 0.8;
                //     console.log('更新后:', middle_shebei[selectdevice].position.x);

                //     middle_shebei[selectdevice].updateMatrixWorld(true);
                //     controls.update();
                //     console.log(`bigScreen.html 555 ['跟新']`, '跟新');
                // } else {
                //     console.error('预期的 Three.js 对象不存在');
                // }
                con_position();
            });
            x_decrease.addEventListener('click', (e) => {
                e.preventDefault(); // 防止默认行为
                e.stopPropagation(); // 阻止事件冒泡到全局监听器
                middle_shebei[selectdevice].position.x -= 0.05;
                con_position();
            });
            y_increase.addEventListener('click', (e) => {
                e.preventDefault(); // 防止默认行为
                e.stopPropagation(); // 阻止事件冒泡到全局监听器
                middle_shebei[selectdevice].position.y += 0.05;
                con_position();
            });
            y_decrease.addEventListener('click', (e) => {
                e.preventDefault(); // 防止默认行为
                e.stopPropagation(); // 阻止事件冒泡到全局监听器
                middle_shebei[selectdevice].position.y -= 0.05;
                con_position();
            });

            // 还原 初始化的场景
            const reset_btn = document.getElementById('reset_btn');
            reset_btn.addEventListener('click', () => {
                controls.reset();
                controls.update(); // 更新控制器
                renderer.render(scene, camera); // 渲染场景
                labelRenderer.render(scene, camera); // 渲染标签
            });
        })
    </script>

    <script src="./chartRender.js"></script>

</body>

</htm>